/*
 * @(#)MaintEmailArchiveAction.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */

package com.dcivision.dms.web;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.dcivision.dms.bean.DmsDocument;
import com.dcivision.dms.core.DocumentEmailArchiveManager;
import com.dcivision.dms.core.DocumentValidateManager;
import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.Crypt;
import com.dcivision.framework.ErrorConstant;
import com.dcivision.framework.GlobalConstant;
import com.dcivision.framework.SystemFunctionConstant;
import com.dcivision.framework.SystemParameterConstant;
import com.dcivision.framework.SystemParameterFactory;
import com.dcivision.framework.TextUtility;
import com.dcivision.framework.Utility;
import com.dcivision.framework.web.AbstractActionForm;
import com.dcivision.framework.web.AbstractMaintAction;
import com.dcivision.mail.bean.EmailMessage;
import com.dcivision.mail.bean.EmailMessageImpl;
import com.dcivision.mail.bean.MailSetting;
import com.dcivision.mail.core.EmailReceiverImpl;
import com.dcivision.mail.dao.MailSettingDAObject;
import com.dcivision.mail.web.MaintMailSettingForm;

/**
 MaintEmailArchiveAction.java

 This class about mail control all action in Email Archive.

 @author      Holmes Yan
 @company     DCIVision Limited
 @creation date   18/07/2004
 @version     $Revision: 1.25 $
 */

public class MaintEmailArchiveAction extends AbstractMaintAction {
  public static final String REVISION = "$Revision: 1.25 $";

  int fileNameIndex;
  /**
   * getMajorDAOClassName
   * 
   * @return The class name of the major DAObject will be used in this action.
   */
  public String getMajorDAOClassName() {
    return ("com.dcivision.mail.dao.ListEmailArchiveDAObject");
  }

  /**
   * getFunctionCode
   * 
   * @return The corresponding system function code of action.
   */
  public String getFunctionCode() {
    return (SystemFunctionConstant.DMS_EMAIL_ARCHIVE);
  }

  public MaintEmailArchiveAction() {
    super();
  }

  public ActionForward execute(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response)throws ServletException {

    AbstractActionForm maintForm = (AbstractActionForm) form;

    String opMode = maintForm.getOpMode();
    String navMode = maintForm.getNavMode();
    log.debug(((maintForm != null) ? maintForm.getClass().getName() : "")+ ", OP Mode:" + opMode + ", Nav Mode:" + navMode);

    // Set the function code for current action.
    ActionForward forward = this.retrieveFunctionCode(request, response,mapping);
    if (forward != null) {
      return forward;
    }
	  try{    
      if (!Utility.isEmpty(opMode)) {
        if ("SAVE_EMAIL_ACCOUNT".equals(opMode)) {//opMod
          try {
            saveEmailAccount(mapping, maintForm, request, response);
            this.commit(request);
            addMessage(request, MESSAGE_RECORD_INSERT);                        
          } catch (ApplicationException appEx) {                        
            this.rollback(request);
            handleApplicationException(request, appEx);
          }
          selectRecord(mapping, maintForm, request, response);               
          return mapping.findForward("NEW.EMAI_ACCOUNT");
        } else if ("SaveAttachment".equals(opMode)) {//opMod
          try {
            saveAttachmentsAsDocuments(mapping, maintForm, request,response);
            this.commit(request);
            addMessage(request, MESSAGE_RECORD_INSERT);
          } catch (ApplicationException appEx) {
            this.rollback(request);
            handleApplicationException(request, appEx);
          }
          getMessageContent(mapping, maintForm, request, response);
          return mapping.findForward("ARCHIVE_DMS_EMAIL");
        } else if ("SaveEmailWithSelectedAttachments".equals(opMode)) {//opMod
          try {
            saveEmailWithSelectedAttachmentsAsCompoundDocument(mapping, maintForm, request, response);
            this.commit(request);
            addMessage(request, MESSAGE_RECORD_INSERT);
          } catch (ApplicationException appEx) {
            this.rollback(request);
            handleApplicationException(request, appEx);
          }
          getMessageContent(mapping, maintForm, request, response);
          return mapping.findForward("ARCHIVE_DMS_EMAIL");
        } else {
          // Unknown operation.
          throw new ApplicationException(ErrorConstant.COMMON_UNKNOWN_OPERATION);
        }
      } else {
	      
        if (Utility.isEmpty(navMode)|| "new_email_account".equals(navMode)) {
          // New navigation.
          this.init(mapping, maintForm, request, response);
          selectRecord(mapping, maintForm, request, response);                    
          return mapping.findForward("NEW.EMAI_ACCOUNT");
        } else if ("ARCHIVE_DMS_EMAIL".equals(navMode)) {
            getMessageContent(mapping, maintForm, request, response);
          return mapping.findForward("ARCHIVE_DMS_EMAIL");
        } else if ("VIEW_EMAIL_CONTENT".equals(navMode)) {
            getMessageContent(mapping, maintForm, request, response);
          return mapping.findForward("VIEW_EMAIL_CONTENT");                    
        } else if ("View_Email_DETAIL".equals(navMode)) {//navMod
          return super.execute(mapping, form, request, response);
        } else {
          // Unknown navigation.
          throw new ApplicationException(ErrorConstant.COMMON_UNKNOWN_NAVIGATION);
        }
      }
	  } catch (ApplicationException appEx) {
	    this.rollback(request);
	    handleApplicationException(request, appEx);
	  }
    return mapping.findForward(GlobalConstant.NAV_MODE_LIST);
  }


  /* (non-Javadoc)
 * @see com.dcivision.framework.web.AbstractMaintAction#selectRecord(org.apache.struts.action.ActionMapping, com.dcivision.framework.web.AbstractActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
 */
  public void selectRecord(ActionMapping mapping, AbstractActionForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {    
    //get mail sestting information
    MailSettingDAObject msd = new MailSettingDAObject(this.getSessionContainer(request), this.getConnection(request));
    Integer userRecordID = this.getSessionContainer(request).getUserRecordID();
    MailSetting mailSetting = (MailSetting) msd.getObjectByUserRecordID(userRecordID);
    MaintMailSettingForm maintForm = (MaintMailSettingForm)form;
    if(!Utility.isEmpty(mailSetting)){
      maintForm.setFormData(mailSetting);
    }
  }

  /**
   * getMessageContent
   * @param mapping
   * @param form
   * @param request
   * @param response
   * @throws ApplicationException
  */
  public void getMessageContent(ActionMapping mapping, AbstractActionForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    String mailid = ((MaintMailSettingForm)form).getMailID();
    //get mail account information
    MailSettingDAObject msd = new MailSettingDAObject(this.getSessionContainer(request), this.getConnection(request));
    Integer userRecordID = this.getSessionContainer(request).getUserRecordID();
    MailSetting mailSetting = (MailSetting) msd.getObjectByUserRecordID(userRecordID);
    
    DocumentEmailArchiveManager manager = new DocumentEmailArchiveManager(this.getSessionContainer(request), this.getConnection(request),mailSetting.getMailServerType());
    EmailMessage emailMessage = manager.getMessageContent(request,mailid,mailSetting.getMailServerType());    
    request.setAttribute("emailMessage", emailMessage);
   
  }    

  /**
   * saveAttachmentsAsDocuments
   * @param mapping
   * @param form
   * @param request
   * @param response
   * @throws ApplicationException
  */
  public void saveAttachmentsAsDocuments(ActionMapping mapping, AbstractActionForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    //get mail account information
  MailSettingDAObject msd = new MailSettingDAObject(this.getSessionContainer(request), this.getConnection(request));
  Integer userRecordID = this.getSessionContainer(request).getUserRecordID();
  MailSetting mailSetting = (MailSetting) msd.getObjectByUserRecordID(userRecordID);
  DocumentEmailArchiveManager manager = new DocumentEmailArchiveManager(this.getSessionContainer(request), this.getConnection(request),mailSetting.getMailServerType());
    manager.saveAttachmentsAsDocuments(request);    
  }
  
  /**
   * saveEmailWithSelectedAttachmentsAsCompoundDocument
   * @param mapping
   * @param form
   * @param request
   * @param response
   * @throws ApplicationException
 */
  public void saveEmailWithSelectedAttachmentsAsCompoundDocument(ActionMapping mapping, AbstractActionForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
  //get mail account information
  MailSettingDAObject msd = new MailSettingDAObject(this.getSessionContainer(request), this.getConnection(request));
  Integer userRecordID = this.getSessionContainer(request).getUserRecordID();
    MailSetting mailSetting = (MailSetting) msd.getObjectByUserRecordID(userRecordID);
    
    //check doc name if duplica
//    if (checkDuplicateSubject(request)){
//        throw new ApplicationException(DmsErrorConstant.MESSAGE_EMAILARCHIVE_DUPLICATE_EMAIL_SUBJECT_ERROR);
//    }
    
    DocumentEmailArchiveManager manager = new DocumentEmailArchiveManager(this.getSessionContainer(request), this.getConnection(request),mailSetting.getMailServerType());
    manager.saveEmailWithSelectedAttachmentsAsCompoundDocument(request);    

  }      

  /**
   * encodeEmail
   * @param mapping
   * @param form
   * @param request
   * @param response
   * @throws ApplicationException
   */
  public void encodeEmail(ActionMapping mapping, AbstractActionForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    String charset = request.getParameter("charset");
    if(charset == null){
      return ;
    }
    //get mail account information
    MailSettingDAObject msd = new MailSettingDAObject(this.getSessionContainer(request), this.getConnection(request));
    Integer userRecordID = this.getSessionContainer(request).getUserRecordID();
    MailSetting mailSetting = (MailSetting) msd.getObjectByUserRecordID(userRecordID);
    
    DocumentEmailArchiveManager manager = new DocumentEmailArchiveManager(this.getSessionContainer(request), this.getConnection(request),mailSetting.getMailServerType());
    manager.reAnalysByOriEmailFAttachment(request,charset);    
    
  }  
  
  
  /**
   * saveEmailAccount
   * @param mapping
   * @param form
   * @param request
   * @param response
   * @throws ApplicationException
   */
  private void saveEmailAccount(ActionMapping mapping,AbstractActionForm form, HttpServletRequest request,HttpServletResponse response) throws ApplicationException {
    MaintMailSettingForm mailSettingForm;
    mailSettingForm = (MaintMailSettingForm) form;
    try {
      MailSetting mailSetting = (MailSetting) mailSettingForm.getFormData();
      //saveEmailAccount(ea);
      Integer userRecordID = this.getSessionContainer(request).getUserRecordID();
      MailSettingDAObject msdo = new MailSettingDAObject(this.getSessionContainer(request), this.getConnection(request));
            
      mailSetting.setOutgoingServerHost("dcivision.com");
      mailSetting.setOutgoingServerPort(new Integer(80));
      mailSetting.setOutgoingServerLoginName("Tester");
      mailSetting.setOutgoingServerLoginPwd("password");      
      
      String password = Crypt.encrypt(mailSetting.getIncomingServerLoginPwd(),SystemParameterFactory.getSystemParameter(SystemParameterConstant.CRYPTO_SALT));
      mailSetting.setIncomingServerLoginPwd(password);
      mailSetting.setUserRecordID(userRecordID);
      
      MailSetting oldMailSetting = (MailSetting) msdo.getObjectByUserRecordID(userRecordID);
      if (oldMailSetting == null) {
        msdo.insert(mailSetting);
      } else {
        mailSetting.setID(oldMailSetting.getID());
        mailSetting.setUpdateCount(oldMailSetting.getUpdateCount());
        msdo.update(mailSetting);
      }
      request.getSession(true).setAttribute("sessEmailList", null);
    } catch (Exception ex) {
    }
  }

  /** Method checkDuplicateSubject()
   * @param request
   * @return
   * @throws ApplicationException
   */
  private boolean checkDuplicateSubject(HttpServletRequest request) throws ApplicationException {
    List duplicateNameList;
    List selectedEmails;
    String[] basicSelectedIDs = request.getParameterValues("basicSelectedID");
    String autoCutFileName = request.getParameter("autoCutFileName") ;        
    List sessEmailList = (List) request.getSession(true).getAttribute("sessEmailList");
    
    if (Utility.isEmpty(basicSelectedIDs)) {
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR);
    }          
          
    if (basicSelectedIDs == null || sessEmailList == null|| sessEmailList.isEmpty()){
        return false;
    }        

    DocumentValidateManager manager = new DocumentValidateManager(this.getSessionContainer(request), this.getConnection(request));
    String hiddenRootID = request.getParameter("targetRootID");
    String hiddenParentID = request.getParameter("destinationID");
    request.setAttribute("targetRootID", hiddenRootID);
    request.setAttribute("destinationID", hiddenParentID);
    duplicateNameList = new ArrayList();
    selectedEmails = new ArrayList();
    for (int i = 0; i < basicSelectedIDs.length; i++) {
      boolean hasDuplicate = false;
      String mailSubject1 = request.getParameter("mailSubject"+ basicSelectedIDs[i]);
      for (int j = 0; j < basicSelectedIDs.length; j++) {
        if (!basicSelectedIDs[i].equals(basicSelectedIDs[j])) {
          String mailSubject2 = request.getParameter("mailSubject"+ basicSelectedIDs[j]);
          if (mailSubject1.equals(mailSubject2)) {
            hasDuplicate = true;
          }
        }
      }
      if (hasDuplicate) {
        duplicateNameList.add((TextUtility.parseIntegerObj(basicSelectedIDs[i])));
        this.addError(request,"dms.label.email_archive.subject_already_exist",mailSubject1);
      }
      selectedEmails.add(TextUtility.parseIntegerObj(basicSelectedIDs[i]));
    }
    request.setAttribute("selectedEmails", selectedEmails);
    if (duplicateNameList != null && duplicateNameList.size() > 0) {
      request.setAttribute("duplicateNameList", duplicateNameList);
      return true;
    }

    for (int i = 0; i < sessEmailList.size(); i++) {
      EmailMessageImpl message = (EmailMessageImpl) sessEmailList.get(i);
      for (int j = 0; j < basicSelectedIDs.length; j++) {
        if (Integer.parseInt(basicSelectedIDs[j]) == (message.getID().intValue())) {
            DmsDocument doc = new DmsDocument();
            String mailSubject = request.getParameter("mailSubject"+ basicSelectedIDs[j]);
            if (mailSubject != null) {
              mailSubject = TextUtility.replaceInvalidChar(mailSubject, EmailReceiverImpl.REPLACE_INVALID_CHAR);
              request.setAttribute("mailSubject"+ basicSelectedIDs[j], mailSubject);
              doc.setDocumentName(mailSubject.trim() + ".html");
            } else {
                doc.setDocumentName(TextUtility.replaceInvalidChar(message.getSubject().trim(),EmailReceiverImpl.REPLACE_INVALID_CHAR)+ ".html");
            }
            doc.setParentID(TextUtility.parseIntegerObj(hiddenParentID));
            doc.setRootID(TextUtility.parseIntegerObj(hiddenRootID));
            doc.setDocumentType("C");
            doc.setItemStatus("A");
            boolean checDuplicate = manager.checkNameExistence(doc);
            int fileNameLength = TextUtility.parseInteger(SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_MAX_UPLOAD_FILENAME_LENGTH));
            if (checDuplicate|| ( !"true".equals(autoCutFileName) &&  fileNameLength < doc.getDocumentName().length())) {
              duplicateNameList.add(message.getID());
              if (checDuplicate) {
                this.addError(request,"dms.label.email_archive.subject_already_exist",message.getSubject());
              } else if ( !"true".equals(autoCutFileName) &&  fileNameLength < doc.getDocumentName().length()) {
                this.addError(request,"dms.message.document_file_name_length_exceeded",message.getSubject());
              }
            }
        }
      }
    }

    if (duplicateNameList != null && duplicateNameList.size() > 0) {
      request.setAttribute("duplicateNameList", duplicateNameList);
      return true;
    }        
    return false;
  }
  
    
}
